<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html>
<head>
<title>Drag &amp; Drop</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="GUI, Mono, Visual Basic, drag &amp; drop, Winforms, tutorial, Linux, programming">
<meta name="description" content="Drag &amp; drop">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>


<div class="content">


<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Drag &amp; Drop</h1>

<p>
This part of the Mono Visual Basic Winforms tutorial
will be dedicated to the drag &amp; drop operations. 
</p>

<div class="center">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* top_horizontal */
google_ad_slot = "3327173442";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<p>
In computer graphical user interfaces, drag-and-drop is the action of (or support for the action of)
clicking on a virtual object and dragging it to a different location or onto another virtual object. 
In general, it can be used to invoke many kinds of actions, or create various types 
of associations between two abstract objects. (Wikipedia)
</p>

<p>
Drag and drop functionality is one of the most visible aspects of the graphical user interface. 
Drag and drop operation enables you to do complex things intuitively. 
</p>


<h2>Dragging a button</h2>

<p>
In the first example, we will do the drag &amp; drop operation on the button control. 
The example does the job outside the drag &amp; drop protocol. 
</p>

<pre class="code">
' ZetCode Mono Visual Basic Winforms tutorial
'
' In this program we drag &amp; drop
' a button control
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com

Imports System.Windows.Forms
Imports System.Drawing


Public Class WinVBApp
    Inherits Form

    Private isDragging As Boolean = False
    Private oldX As Integer
    Private oldY As Integer
    Private button As Button


    Public Sub New

        Me.Text = "Drag &amp; Drop button"
        Me.Size = New Size(270, 180)
       
        Me.InitUI
       
        Me.CenterToScreen

    End Sub
    
    Private Sub InitUI
    
        button = New Button
        button.Parent = Me
        button.Cursor = Cursors.Hand
        button.Text = "Button"
        button.Location = New Point(20, 20)

        AddHandler button.MouseDown, AddressOf Me.OnMouseDown
        AddHandler button.MouseUp, AddressOf Me.OnMouseUp
        AddHandler button.MouseMove, AddressOf Me.OnMouseMove

    End Sub
    
    Private Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
        isDragging = True
        oldX = e.X
        oldY = e.Y
    End Sub

    Private Sub OnMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
        If isDragging
            button.Top = button.Top + (e.Y - oldY)
            button.Left = button.Left + (e.X - oldX)
        End If
    End Sub
    
    Private Sub OnMouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
        isDragging = False
    End Sub
    

    Public Shared Sub Main
        Application.Run(New WinVBApp)
    End Sub
   
End Class
</pre>


<p>
The code example puts a regular button control on the form container. 
By clicking on the button surface and simultaneously dragging it with
a mouse we can relocate the button. 
</p>

<p>
There are some supporting variables in our example. The 
<b class="keyword">isDragging</b> variable tells us, whether we are
in the process of dragging an object. The <b class="keyword">oldX</b> 
and <b class="keyword">oldY</b> variables
store the x, y coordinates just before the dragging process begins. 
</p>

<pre class="explanation">
 AddHandler button.MouseDown, AddressOf Me.OnMouseDown
 AddHandler button.MouseUp, AddressOf Me.OnMouseUp
 AddHandler button.MouseMove, AddressOf Me.OnMouseMove
</pre>

<p>
We plug in three different mouse handlers for our button. 
They implement three different stages of the drag &amp; drop process. 
The process begins, when we click on the button. This is handled by the
<b class="keyword">OnMouseDown</b> method. The second
part is the movement. This is when we move the object to a new position.
It is handled in the <b class="keyword">OnMouseMove</b> method.
The final part is when the process stops. It happens when we release 
the mouse button. The appropriate task is delegated to the
<b class="keyword">OnMouseUp</b> method.
</p>

<pre class="explanation">
 Private Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
     isDragging = True
     oldX = e.X
     oldY = e.Y
 End Sub
</pre>

<p>
The <b class="keyword">OnMouseDown</b> method implements the first 
part of the process. It sets three necessary variables. 
</p>


<pre class="explanation">
 Private Sub OnMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
     If isDragging
         button.Top = button.Top + (e.Y - oldY)
         button.Left = button.Left + (e.X - oldX)
     End If
 End Sub
</pre>

<p>
In the <b class="keyword">OnMouseMove</b> method, we relocate the button. 
We calculate the difference between the 
stored x, y coordinates and the new coordinates of the mouse pointer. 
The difference is added to the <b class="keyword">Top</b> and 
<b class="keyword">Left</b> properties of the button, thus moving 
it to a new position.
</p>


<br>
<img src="/img/gui/vbwinf/dragbutton.png" alt="Dragging a button">
<div class="figure">Figure: Dragging a button</div>


<h2>Dragging Text</h2>

<p>
In the previous example, we did drag &amp; drop on the control. Next we will do a drag &amp; 
drop operation on the textual data. 
Here we will use the drag &amp; drop protocol provided by the Winforms library.
</p>

<p>
Drag &amp; drop operation is a standardized communication protocol in Winforms. We have 
two basic objects. The <b>drag source</b> and
the <b>drop target</b>.  
</p>

<pre class="code">
' ZetCode Mono Visual Basic Winforms tutorial
'
' In this program we drag &amp; drop
' text
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com

Imports System.Windows.Forms
Imports System.Drawing


Public Class WinVBApp
    Inherits Form
    
    Private txtBox As TextBox
    Private btn As Button

    Public Sub New

       Me.Text = "Drag &amp; Drop text"
       Me.Size = New Size(250, 200)
       
       Me.InitUI
       
       Me.CenterToScreen

    End Sub
    
    Private Sub InitUI
    
        btn = New Button
        txtBox = New TextBox
        Me.SuspendLayout

        btn.AllowDrop = True
        btn.Location = New Point(150, 50)
        txtBox.Location = New Point(15, 50)

        Me.Controls.Add(btn)
        Me.Controls.Add(txtBox)
        Me.ResumeLayout

        AddHandler btn.DragEnter, AddressOf Me.OnDragEnter
        AddHandler btn.DragDrop, AddressOf Me.OnDragDrop
        AddHandler txtBox.MouseDown, AddressOf Me.OnMouseDown

    End Sub
    
    Private Sub OnDragEnter(ByVal sender As Object, ByVal e As DragEventArgs)
        e.Effect = DragDropEffects.Copy
    End Sub

    Private Sub OnDragDrop(ByVal sender As Object, ByVal e As DragEventArgs)
        sender.Text = e.Data.GetData(DataFormats.Text)
    End Sub

    Private Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
        sender.DoDragDrop(sender.Text, DragDropEffects.Copy)
    End Sub
    

    Public Shared Sub Main
        Application.Run(New WinVBApp)
    End Sub
   
End Class
</pre>

<p>
We have two controls on the form. A button and a text box. We will drag 
text from the text box and
drop it on the button. 
</p>


<pre class="explanation">
 btn.AllowDrop = True
</pre>

<p>
We set the <b class="keyword">AllowDrop</b> property to true. Dropping 
is not enabled by default. 
</p>

<pre class="explanation">
 AddHandler btn.DragEnter, AddressOf Me.OnDragEnter
 AddHandler btn.DragDrop, AddressOf Me.OnDragDrop
 AddHandler txtBox.MouseDown, AddressOf Me.OnMouseDown
</pre>

<p>
Again, the drag &amp; drop process is divided into three steps. We have 
three methods for each particular step. 
</p>

<pre class="explanation">
 Private Sub OnDragEnter(ByVal sender As Object, ByVal e As DragEventArgs)
     e.Effect = DragDropEffects.Copy
 End Sub
</pre>

<p>
The <b class="keyword">DragEnter</b> event is launched when the mouse 
pointer enters the area of the drop target control.
The <b class="keyword">Effect</b> property must be set. The DragDropEffects 
of the drag source and drop target must be equal.
Otherwise the operation will not work. 
</p>


<pre class="explanation">
 Private Sub OnDragDrop(ByVal sender As Object, ByVal e As DragEventArgs)
     sender.Text = e.Data.GetData(DataFormats.Text)
 End Sub
</pre>

<p>
Finally we have the <b class="keyword">OnDragDrop</b> method. Here we get the data from the event object and
set it to the button <b class="keyword">Text</b> property.
</p>

<pre class="explanation">
 Private Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
     sender.DoDragDrop(sender.Text, DragDropEffects.Copy)
 End Sub
</pre>

<p>
In the <b class="keyword">OnMouseDown</b> method we initialize the drap &amp; drop process. We initiate the process 
with the <b class="keyword">DoDragDrop</b> method. The <b class="keyword">DragDropEffects.Copy</b>
parameter specifies the type of the operation. Esentially, we can either copy the text or move it 
during the drag &amp; drop operation. 
</p>

<br>
<img src="/img/gui/vbwinf/dragtext.png" alt="Drag &amp; drop of text">
<div class="figure">Figure: Drag &amp; drop of text</div>



<h2>Dragging Image</h2>

<p>
In our last example, we will drag &amp; drop image on the form. 
</p>


<pre class="code">
' ZetCode Mono Visual Basic Winforms tutorial
'
' In this program we drag &amp; drop
' an image
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com

Imports System.Windows.Forms
Imports System.Drawing


Public Class WinVBApp
    Inherits Form

    Private IsDragging As Boolean = False
    Private oldX As Integer
    Private oldY As Integer
    
    Private dropRect As Rectangle
    Private picBox As PictureBox
    Private image As Bitmap
    Private brsh As Brush

    Public Sub New

        Me.Text = "Drag &amp; Drop image"
        Me.Size = New Size(350, 250)
       
        Me.InitUI
       
        Me.CenterToScreen

    End Sub
    
    Private Sub InitUI
    
        isDragging = False
        dropRect = New Rectangle(10, 10, 200, 160)
        brsh = Brushes.Gray
        picBox = New PictureBox
        Me.LoadImage

        picBox.Parent = Me
        picBox.Location = New Point(100, 50)
        picBox.Size = New Size(image.Width, image.Height)
        picBox.Image = image
        picBox.Cursor = Cursors.Hand

        AddHandler Me.Paint, AddressOf Me.OnPaint

        AddHandler picBox.MouseDown, AddressOf Me.OnMouseDown        
        AddHandler picBox.MouseMove, AddressOf Me.OnMouseMove
        AddHandler picBox.MouseUp, AddressOf Me.OnMouseUp

    End Sub
    
    Private Sub LoadImage
    
      Try 
          image = New Bitmap("image.jpg")
      Catch 
          Console.WriteLine("Error reading image")
          Environment.Exit(1)
      End Try
      
    End Sub  
    
    Private Sub OnMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
        isDragging = True
        oldX = e.X
        oldY = e.Y
    End Sub

    Private Sub OnMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
        If isDragging
            picBox.Top = picBox.Top + (e.Y - oldY)
            picBox.Left = picBox.Left + (e.X - oldX)
        End If
    End Sub
    
    Private Sub OnMouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
    
        isDragging = False

        If dropRect.Contains(picBox.Bounds)
            brsh = Brushes.Gold
        Else 
            brsh = Brushes.Gray
        End If

        Me.Refresh
        
    End Sub
    
    Private Sub OnPaint(ByVal sender As Object, ByVal e As PaintEventArgs)
        Dim g As Graphics = e.Graphics
        g.FillRectangle(brsh, dropRect)
    End Sub
    
    
    Public Shared Sub Main
        Application.Run(New WinVBApp)
    End Sub
   
End Class
</pre>

<p>
In our example we have a <b class="keyword">PictureBox</b> and we draw a gray rectangle. 
If we drop the picture inside the rectangle, the color of the rectangle changes to gold. 
</p>

<pre class="explanation">
 brsh = Brushes.Gray
</pre>

<p>
The <b class="keyword">brsh</b> variable holds the brush of the rectangle. 
It is a gray color by default.  
</p>

<pre class="explanation">
 Private Sub LoadImage

   Try 
       image = New Bitmap("image.jpg")
   Catch 
       Console.WriteLine("Error reading image")
       Environment.Exit(1)
   End Try
  
 End Sub  
</pre>

<p>
The <b class="keyword">LoadImage</b> method loads a bitmap 
for the <b class="keyword">PictureBox</b> control.
</p>

<pre class="explanation">
 If dropRect.Contains(picBox.Bounds)
     brsh = Brushes.Gold
 Else 
     brsh = Brushes.Gray
 End If
</pre>

<p>
In the <b class="keyword">OnMouseUp</b> method, we determine the brush 
of the rectangle. If the bounds of the 
picture box are inside the rectangle, the brush is of gold color; 
gray otherwise.
</p>

<pre class="explanation">
 Me.Refresh
</pre>

<p>
We must call the <b class="keyword">Refresh</b> method to activate the new brush color. 
</p>

<br>
<img src="/img/gui/vbwinf/dragimage.png" alt="Drag & drop image">
<div class="figure">Figure: Drag &amp; drop image</div>


<hr class="btm">

<p>
This chapter was dedicated to drag &amp; drop operations using the Mono Winforms 
library with the Visual Basic language. 
</p>

<br>
<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div>
<br>


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified June 9, 2009  <span class="copyright">&copy; 2007 - 2012 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>

